package gui;

import java.awt.Component;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.MalformedURLException;
import java.net.URL;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.Properties;

import javax.jms.Connection;
import javax.jms.ConnectionFactory;
import javax.jms.JMSException;
import javax.jms.Session;
import javax.jms.Topic;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.swing.DefaultListModel;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JTabbedPane;
import javax.swing.JTextArea;
import javax.swing.border.EmptyBorder;
import javax.xml.namespace.QName;
import javax.xml.ws.Service;

import listeners.MDBListener;
import listeners.UpdateUserListener;
import model.Message;
import model.User;
import net.miginfocom.swing.MigLayout;
import webservice.ChatServiceWS;

public class MainFrame extends JFrame {

	private JPanel contentPane;
	private static MainFrame instance = null;
	private MyTabbedPane tabbedPane = new MyTabbedPane(JTabbedPane.TOP);
	private JTextArea textAreaMessages = new JTextArea();
	//private JList list = new JList();
	private DefaultListModel<User> userListModel;
	private InputPanel inputPanel;
	private User currentUser;
	private Topic topic;
	private Connection connection;
	private Session session;
	private MDBListener mdbListener;
	private UpdateUserListener updtUsrListner;
	private String username="admin";
	private String password="pass";
	private boolean registerUser=false;
	private String localAddress;//="192.168.1.2";
	private String loginUsername;
	private String loginPassword;
	
	public static MainFrame getInstance() {
		if (instance == null) {
			instance = new MainFrame();
		}
		return instance;
	}

	private void initComponents() {
		// TODO Auto-generated method stub
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		setBounds(100, 100, 640, 480);
		contentPane = new JPanel();
		contentPane.setBorder(new EmptyBorder(5, 5, 5, 5));
		setContentPane(contentPane);
		contentPane.setLayout(new MigLayout("", "[grow][][]", "[371.00,grow][grow]"));
		
		tabbedPane.addTab("Public chat", new ChatTab());
		contentPane.add(tabbedPane, "cell 0 0,grow");

		inputPanel = new InputPanel(session,topic);
		contentPane.add(inputPanel, "cell 0 1,grow");
	}

	/**
	 * Create the frame.
	 */
	public MainFrame() {
		super();
		
		//Ucitavanje adrese iz konfiguracionog fajla
		Properties prop = new Properties();
		InputStream input = null;
		
		try {
			 
			input = new FileInputStream("../chatAgentsEAR/properties/config.properties");
	 
			// load a properties file
			prop.load(input);
	 
			// get the property value and print it out
			localAddress = prop.getProperty("ServerAddress");
	 
		} catch (IOException ex) {
			try {
				 
				input = new FileInputStream("config.properties");
		 
				// load a properties file
				prop.load(input);
		 
				// get the property value and print it out
				localAddress = prop.getProperty("ServerAddress");
		 
			} catch (IOException exc) {
				ex.printStackTrace();
			}
		} finally {
			System.out.println("resources cleaned");
			if (input != null) {
				try {
					input.close();
				} catch (IOException e) {
					e.printStackTrace();
				}
			}
		}
		//Ucitavanje adrese iz konfiguracionog fajla
		setLocationRelativeTo(null);
		userListModel = new DefaultListModel<User>();
		setTitle("Chat client, logged out.");
		connectToServer();
		initComponents();
		setResizable(false);
		addWindowListener(new WindowAdapter() {
			@Override
			public void windowClosing(WindowEvent e) {
				// TODO Auto-generated method stub
				super.windowClosing(e);
				try{
					disconnectFromServer();
				}
				catch (Exception wsE) {
					//just exit
				}
			}
		});
	}

	public MyTabbedPane getTabbedPane() {
		return tabbedPane;
	}
	/**
	 * displayMessage koji u zavisnosti od trenutno otvorenog taba prikazuje poruku. 
	 * to znaci da je trenutno napravljen da radi samo sa slanjem!!
	 * @param message
	 */
	@Deprecated
	public void displayMessage(Message message) {
		SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss");
		
		String displayString="["+sdf.format(message.getDate())+"] ";
		displayString+="["+message.getFrom().getUsername()+"@"+message.getFrom().getHost().getAlias()+"]: ";
		displayString+=message.getContent();
		
		int selectedIndex=tabbedPane.getSelectedIndex();
		if(selectedIndex==0) {
			textAreaMessages.append(displayString+"\n");
		}
		else if(selectedIndex!=-1) {
			Component cmp=tabbedPane.getSelectedComponent();
			if(cmp instanceof ChatTab) {
				ChatTab pct=(ChatTab) cmp;
				pct.displayText(displayString+"\n");
			}
		}
	}
	
	public void displayMessage2(model.Message message) {
		SimpleDateFormat sdf = new SimpleDateFormat("HH:mm:ss");
		
		String displayString="["+sdf.format(message.getDate())+"] ";
		displayString+="["+message.getFrom().getUsername()+"@"+message.getFrom().getHost().getAlias()+"]: ";
		displayString+=message.getContent();

		textAreaMessages.append(displayString+"\n");

	}
	
	/**
	 * Ovde se ubacuju podaci o korisnicima u DefaultListModel
	 */
	public void initModel(ArrayList<User> userList) {
		for(User u : userList) {
			//if(!u.equals(currentUser))
				userListModel.addElement(u);
		}
		tabbedPane.getChatTabs().get(0).getList().setModel(userListModel);
		updtUsrListner= new UpdateUserListener(userListModel);
	}

	public InputPanel getInputPanel() {
		return inputPanel;
	}

	public User getCurrentUser() {
		return currentUser;
	}

	public void setCurrentUser(User currentUser) {
		this.currentUser = currentUser;
	}
	
	public void disconnectFromServer() {
		try {
			session.close();
			connection.close();
			Service mojServis = Service
					.create(new URL(
							"http://"+localAddress+":8080/chatAgentsEJB/ChatService/ChatServiceBean?wsdl"),
							new QName("http://1337.webservice", "ChatService"));
			ChatServiceWS servis = mojServis.getPort(ChatServiceWS.class);
			servis.logout(currentUser);
			updtUsrListner.disconnect();
		} catch (JMSException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		catch (MalformedURLException e2) {
			e2.printStackTrace();
		}
	}
	
	public void connectToServer() {
		try {
			final Properties env = new Properties();
			env.put(Context.INITIAL_CONTEXT_FACTORY,
					"org.jboss.naming.remote.client.InitialContextFactory");
			env.put(Context.PROVIDER_URL, "remote://"+localAddress+":4447");
			env.put(Context.SECURITY_PRINCIPAL, "guest");
			env.put(Context.SECURITY_CREDENTIALS, "guestguest");
			Context context = new InitialContext(env);
			ConnectionFactory cf = (ConnectionFactory) context
					.lookup("jms/RemoteConnectionFactory");
			topic = (Topic) context
					.lookup("jms/topic/mojTopic");
			context.close();
			connection = cf.createConnection("guest", "guestguest");
			session = connection.createSession(false,
					Session.AUTO_ACKNOWLEDGE);

			connection.start();	
			mdbListener = new MDBListener(session, topic);
		} catch (Exception ex) {
			ex.printStackTrace();
		}
	}
	
	public User containsUsername(String username) {
		User retUser = null;
		Enumeration<User> enUser = userListModel.elements();
		while(enUser.hasMoreElements()) {
			User user = enUser.nextElement();
			if(username.contains(user.getUsername()))
				retUser=user;
		}
		
		return retUser;
	}

	public DefaultListModel<User> getUserListModel() {
		return userListModel;
	}

	public void setUserListModel(DefaultListModel<User> userListModel) {
		this.userListModel = userListModel;
	}

	public boolean isRegisterUser() {
		return registerUser;
	}

	public void setRegisterUser(boolean registerUser) {
		this.registerUser = registerUser;
	}

	public String getLocalAddress() {
		return localAddress;
	}

	public void setLocalAddress(String localAddress) {
		this.localAddress = localAddress;
	}

	public String getLoginUsername() {
		return loginUsername;
	}

	public void setLoginUsername(String loginUsername) {
		this.loginUsername = loginUsername;
	}

	public String getLoginPassword() {
		return loginPassword;
	}

	public void setLoginPassword(String loginPassword) {
		this.loginPassword = loginPassword;
	}
	
	
}
